/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.treepoke.util.file;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Scanner;

/**
 * This class has a set of static method to process file
 *
 * @author etorres
 */
public class FileUtil {

    
    /**
     * Convierte un stream a una lista de elementos. (Cada elemento de la lista
     * corresponde a cada línea del stream). Es útil para ordenar archivos
     * cuando se utiliza al tiempo con la función listToFile y una función de
     * ordenación.
     *
     * @param f Archivo a convertir
     * @return Una lista de elementos que se corresponden con las líneas del
     * archivo
     * @author etorres
     */
    public static List<String> fileToList(Reader r) throws IOException {
        List<String> l = new ArrayList<String>();
        BufferedReader read = new BufferedReader(r);
        String linea = null;
        while ((linea = read.readLine()) != null) {
            l.add(linea);
        }
        read.close();
        return (l.size() > 0) ? l : null;
    }    
    
    /**
     * @param f Archivo a convertir
     * @author etorres
     */
    public static List<String> fileToList(File f) throws IOException {
        return fileToList(new FileReader(f));
    }

    /**
     * @param inputStream InputStream a convertir
     * @author etorres @modify dpulido
     */
    public static List<String> fileToList(InputStream inputStream) throws IOException {
        return fileToList(new InputStreamReader(inputStream));
    }
    
    /**
     * Convierte una lista de elementos a un archivo. (Cada elemento de la lista
     * corresponde a cada línea del archivo). Es útil para ordenar archivos
     * cuando se utiliza al tiempo con la función fileToList y una función de
     * ordenación.
     *
     * @param l Lista a convertir
     * @param f Archivo en el que se va a guardar la lista
     * @author etorres
     */
    public static void listToFile(List<String> l, File f) throws IOException {
        PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter(f)));
        for (String s : l) {
            out.println(s);
        }
        out.flush();
        out.close();
    }

    public static void copy(File src, File dst)
            throws IOException {
        copy(new FileInputStream(src), new FileOutputStream(dst));
    }

    /**
     * Copia el contenido del stream in en el stream out.
     *
     * @throws IOException
     * @param in
     * @param out
     * @author ELTV
     */
    public static void copy(InputStream in, OutputStream out) throws IOException {
        /*
         * long tiempoInicial = Calendar.getInstance().getTimeInMillis();
         * System.out.print("Copiando: " + src.getName() + "... ");
         */

        // Transfer bytes from in to out
        byte[] buf = new byte[1024];
        int len;
        while ((len = in.read(buf)) > 0) {
            out.write(buf, 0, len);
        }
        in.close();
        out.close();

        /*
         * long tiempoFinal = Calendar.getInstance().getTimeInMillis();
         * System.out.println("Archivo copiado. Tiempo total: " + ((tiempoFinal
         * - tiempoInicial) / 1000f) + " seg.");
         */
    }
    
    /**
     * Convierte el contenido de un archivo de texto en un String
     * @param f
     * @return
     * @throws IOException 
     * @author http://www.rgagnon.com/javadetails/java-0052.html
     */
    public static String fileToString(File f) throws IOException {
        Scanner scanner = new Scanner(f).useDelimiter("\\Z");
        String s = scanner.next();        
        scanner.close();
        return s;
    }
    
    /**
     * Verifica la existencia (si no existe lo crea) del directorio con la 
     * fecha indicada en el directorio padre
     * @param directorioPadre
     * @param fechaDirectorio
     * @return
     * @throws IOException 
     * @author ELTV
     */
    public static File configurarDirectorioFecha(File directorioPadre,
            Date fechaDirectorio) throws IOException {
        
        SimpleDateFormat formato = new SimpleDateFormat("yyyy/MM/dd");
        File directorioFecha = new File(directorioPadre, formato.format(fechaDirectorio));
        if (!directorioFecha.exists()) {
            directorioFecha.mkdir();
        }

        return directorioFecha;
    }
    
    /**
     * Mueve un archivo de una ruta a otra
     *
     * @param rutaCompletaArchivoAMover
     * @param rutaCompletaNuevoArchivo
     * @throws java.io.IOException
     * @author GVP
     */
    public static void moverArchivo(String rutaCompletaArchivoAMover,
            String rutaCompletaNuevoArchivo) throws IOException {
        moverArchivo(new File(rutaCompletaArchivoAMover),
                new File(rutaCompletaNuevoArchivo));
    }

    /**
     * Mueve un archivo de una ruta a otra
     *
     * @param rutaCompletaArchivoAMover
     * @param rutaCompletaNuevoArchivo
     * @throws java.io.IOException
     * @author GVP
     */
    public static void moverArchivo(File fileArchivoAMover,
            File fileArchivoNuevo) throws IOException {
        fileArchivoAMover.renameTo(fileArchivoNuevo);
    }  
    
    public static File[] fileList(String ruta) {
        File dir = new File(ruta);

        String[] children = dir.list();
        if (children == null) {
            // Either dir does not exist or is not a directory
        } else {
            for (int i = 0; i < children.length; i++) {
                // Get filename of file or directory
                String filename = children[i];
            }
        }

        // It is also possible to filter the list of returned files.
        // This example does not return any files that start with `.'.
        FilenameFilter filter = new FilenameFilter() {

            public boolean accept(File dir, String name) {
                return !name.startsWith(".");
            }
        };
        children = dir.list(filter);

        // The list of files can also be retrieved as File objects
        File[] files = dir.listFiles();

        // This filter only returns directories
        FileFilter fileFilter = new FileFilter() {

            public boolean accept(File file) {
                return file.isDirectory();
            }
        };
        files = dir.listFiles(fileFilter);

        File[] ficheros = dir.listFiles();

        return ficheros;
    }
    
    /**
     * Asigna permisos al archivo enviado
     * @param file
     * @throws IOException 
     */
    public static void asignarPermisos(File file, boolean readable, 
        boolean writable, boolean executable, boolean ownerOnly) {
        file.setReadable(readable, ownerOnly);
        file.setWritable(writable, ownerOnly);
        file.setExecutable(executable, ownerOnly);
    }    

}
